var db = require('bookshelf').bookshelf;
var Database = require('../app/database');
var moment = require('moment');
var util = require('util');
var TemplateBuilder = require('../app/template_builder');

var ActionController = module.exports = {};

log = function(msg) {
    //console.log(new Date().toLocaleTimeString() + ' [action_controller]: ' + msg);
};

ActionController.initialize = function(router) {
	log('initialize.js: ' + util.inspect(router,false,null));
	router
    .add({Method: router.Methods.GET, URL: 'actions', Authorize: router.Access.Registered, Handler: ActionController.getActions})
	.add({Method: router.Methods.GET, URL: 'actions/servers/:id', Authorize: router.Access.Registered, Handler: ActionController.getServerActions})
	.add({Method: router.Methods.GET, URL: 'actions/:id', Authorize: router.Access.Registered, Handler: ActionController.getAction})
	.add({Method: router.Methods.POST, URL: 'actions', Authorize: router.Access.User, Handler: ActionController.saveActions})
	.add({Method: router.Methods.DELETE, URL: 'actions/:id', Authorize: router.Access.Admin, Handler: ActionController.closeAction})
};

ActionController.getActions = function(req, res) {
	log('getActions: ' + req.originalUrl);
    new Database.Collections.Actions()
                .query(function (qb) {
                    var hasFilters = false;
                    if (req.query) {
                        if (req.query.from != null) {
                            req.query.from = moment(req.query.from).format(moment.application_dateformat);
                            qb.where('action_datetime','>',req.query.from);
                            hasFilters = true;
                        };
                        if (req.query.active != null && req.query.active) {
                            qb.whereNull('is_executed').orWhere('is_executed','==','false');
                            hasFilters = true;
                        };
                    };
                    if (!hasFilters) {
                        qb.orderBy('action_id', 'desc');
                    };
                    qb.limit(50);
		        })
                .fetch({withRelated: ['user']})
		        .then(function(resp) {
                    if (resp != null && resp.length && resp.length > 0) {
                        for (var i = 0; i < resp.length; i++){
                            var item = resp.at(i);
                            if (item.related('user') != null) {
                                var user = item.related('user');
                                user.cleanUp();
                                log(util.inspect(user,false,null));
                            };
                        };
                    };
			        res.json(200, resp);
			        log(new Date() + ': replied: ' + util.inspect(resp,false,null));
		        });
};
ActionController.getAction = function(req, res) {
	log('getAction: ' + req.originalUrl);	
	new Database.Models.Config({config_id: req.params.id})
		.fetch()
		.then(function(resp) {
			if (!resp) {
				res.json(404, { status: 404, type: 'Resource', message: 'Not found' });
			} else {
				res.json(200, resp);
			};
			log(new Date() + ': replied: ' + util.inspect(resp,false,null));
		});
};

ActionController.getServerActions = function(req, res) {
	log('getServerActions: ' + req.originalUrl);
    if (req.params && req.params.id) {
	    new Database.Collections.Actions()
            .query(function (qb) {
			    qb.where('server_id', '=', req.params.id) //.andWhere('is_active', '!=', '0');
                var hasFilters = false;
                if (req.query) {
                    if (req.query.from != null) {
                        req.query.from = moment(req.query.from).format(moment.application_dateformat);
                        qb.where('action_datetime','>',req.query.from);
                        hasFilters = true;
                    };
                    if (req.query.active != null && req.query.active) {
                        qb.whereNull('is_executed').orWhere('is_executed','==','false');
                        hasFilters = true;
                    };
                };
                if (!hasFilters) {
                    qb.orderBy('action_id', 'desc');
                };
                qb.limit(50);
		    })
		    .fetch({withRelated: ['user']})
		    .then(function(resp) {
			    res.json(200, resp);
			    log('replied: ' + util.inspect(resp,false,null));
		    });
    } else {
        res.json(500, { status: 500, type: 'Resource', message: 'Argument not valid' });
    };
};
ActionController.saveActions = function(req, res) {
	log('saveActions: ' + req.originalUrl + ' - ' + util.inspect(req.body,false,null));
	if (req.body) {
        var isArray = (req.body instanceof Array);
		var actionArray = [].concat( req.body );
		log('actionArray: ' + util.inspect(actionArray,false,null));
		var isValid = true;
		var actionModels = [];
		for (index = 0; index < actionArray.length; ++index) {
			// TODO: check for validity
            var currentAction = actionArray[index];
            if (currentAction.action_id == null || currentAction.action_id <= 0) {
                currentAction.user_id = req.session.user.user_id;
                currentAction.action_datetime = moment().format(moment.application_dateformat);
            };
            if (currentAction.action_datetime && currentAction.action_datetime.toString().length) {
                var mom = moment.getRightDate(currentAction.action_datetime);
                currentAction.action_datetime = mom.format(moment.application_dateformat);
            };
            if (currentAction.start_datetime && currentAction.start_datetime.toString().length) {
                var mom = moment.getRightDate(currentAction.start_datetime);
                currentAction.start_datetime = mom.format(moment.application_dateformat);
            };
            if (currentAction.end_datetime && currentAction.end_datetime.toString().length) {
                var mom = moment.getRightDate(currentAction.end_datetime);
                currentAction.end_datetime = mom.format(moment.application_dateformat);
            };
            var model = new Database.Models.Action(currentAction)
				.save()
				.then(function(resp) {
					actionModels.push(resp);
                    if (isArray) {
					    if (actionModels.length == actionArray.length) {
						    res.json(200, actionModels);
						    log('replied: ' + util.inspect(actionModels,false,null));
					    };
                    } else {
						res.json(200, resp);
						log('replied: ' + util.inspect(resp,false,null));
                    };
                    if (resp != null) {
                        var model = new Database.Models.Server({server_id: resp.get('server_id')})
                        .fetch()
                        .then(function(resp){
                            resp.set({last_datetime:moment().format(moment.application_dateformat)});
                            resp.save();
                        });
                    };
				});
		};
	} else {
		res.send(500,{ status: 500, type: 'Resource', message: 'Argument not valid' });
	};	
};
ActionController.closeAction = function(req, res) {
	log('closeAction: ' + req.originalUrl + ' - ' + util.inspect(req.body,false,null));
	if (req.params && req.params.id) {
        var model = new Database.Models.Action({ action_id: req.params.id})
        .fetch()
        .then(function(resp) {
            if (resp != null) {
                if (!resp.get('is_executed')) {
                    resp.set({is_processing: false, is_executed:true, is_success:false, end_datetime:moment().format(moment.application_dateformat), status:'Manually Canceled by ' + req.session.user.login});
                    resp
				        .save()
				        .then(function(resp) {
                            if (resp != null) {
                                var arr = [];
                                arr.push(resp);
						        res.json(200, arr);
						        log('replied: ' + util.inspect(resp,false,null));
                            } else {
                                res.send(500,{ status: 500, type: 'Resource', message: 'An error occured during the update process' });
                            };
				        });
                } else {
					res.json(500,{ status: 500, type: 'Resource', message: 'Action is executed already: ' + resp.get('action_id') });
					log('replied: ' + util.inspect(resp,false,null));
                };
            };
        });
	} else {
		res.send(500,{ status: 500, type: 'Resource', message: 'Argument not valid' });
	};	
};